home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / ASSEMBLE / H145.ZIP / ASXXXX_3.ZIP / LKRLOC.C < prev    next >
C/C++ Source or Header  |  1990-07-18  |  8KB  |  529 lines

  1. /* lkrloc.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <alloc.h>
  15. #include "aslink.h"
  16.  
  17.  
  18. /*
  19.  * Process relocation operations
  20.  * and call designated output routine
  21.  */
  22. VOID
  23. reloc(c)
  24. char c;
  25. {
  26.     switch(c) {
  27.  
  28.     case 'T':
  29.         relt();
  30.         break;
  31.  
  32.     case 'R':
  33.         relr();
  34.         break;
  35.  
  36.     case 'P':
  37.         relp();
  38.         break;
  39.  
  40.     case 'E':
  41.         rele();
  42.         break;
  43.  
  44.     default:
  45.         fprintf(stderr, "Undefined Relocation Operation\n");
  46.         break;
  47.  
  48.     }
  49. }
  50.  
  51.  
  52. /*
  53.  * Relocation 'T' processing.
  54.  */
  55. VOID
  56. relt()
  57. {
  58.     rtcnt = 0;
  59.     while (more()) {
  60.         if (rtcnt < NTXT) {
  61.             rtval[rtcnt] = eval();
  62.             rtflg[rtcnt] = 1;
  63.             rtcnt++;
  64.         }
  65.     }
  66. }
  67.  
  68. /*
  69.  * Relocation 'R' processing
  70.  */
  71. VOID
  72. relr()
  73. {
  74.     register mode;
  75.     register addr_t reli, relv;
  76.     int aindex, rindex, rtp, error;
  77.     addr_t r, rtbase, rtofst, paga, pags, pc;
  78.     struct areax **a;
  79.     struct sym **s;
  80.  
  81.     /*
  82.      * Get area and symbol lists
  83.      */
  84.     a = hp->a_list;
  85.     s = hp->s_list;
  86.  
  87.     /*
  88.      * Verify Area Mode
  89.      */
  90.     if (eval() != (R_WORD | R_AREA) || eval())
  91.         fprintf(stderr, "R input error\n");
  92.  
  93.     /*
  94.      * Get area pointer
  95.      */
  96.     aindex = evword();
  97.     if (aindex >= hp->h_narea) {
  98.         fprintf(stderr, "R area error\n");
  99.         return;
  100.     }
  101.  
  102.     /*
  103.      * Base values
  104.      */
  105.     rtbase = add_w(0, 0);
  106.     rtofst = 2;
  107.  
  108.     /*
  109.      * Relocate address
  110.      */
  111.     pc = add_w(a[aindex]->a_addr, 0);
  112.  
  113.     /*
  114.      * Do remaining relocations
  115.      */
  116.     while (more()) {
  117.         error = 0;
  118.         mode = eval();
  119.         rtp = eval();
  120.         rindex = evword();
  121.  
  122.         /*
  123.          * R_SYM or R_AREA references
  124.          */
  125.         if (mode & R_SYM) {
  126.             if (rindex >= hp->h_nglob) {
  127.                 fprintf(stderr, "R symbol error\n");
  128.                 return;
  129.             }
  130.             reli = symval(s[rindex]);
  131.         } else {
  132.             if (rindex >= hp->h_narea) {
  133.                 fprintf(stderr, "R area error\n");
  134.                 return;
  135.             }
  136.             reli = a[rindex]->a_addr;
  137.         }
  138.  
  139.         /*
  140.          * R_PCR addressing
  141.          */
  142.         if (mode & R_PCR) {
  143.             if (mode & R_BYTE) {
  144.                 reli -= (pc + (rtp-rtofst) + 1);
  145.             } else {
  146.                 reli -= (pc + (rtp-rtofst) + 2);
  147.             }
  148.         }
  149.  
  150.         /*
  151.          * R_PAG0 or R_PAG addressing
  152.          */
  153.         if (mode & (R_PAG0|R_PAG)) {
  154.             paga  = sdp.s_area->a_addr;
  155.             pags  = sdp.s_addr;
  156.             reli -= paga + pags;
  157.         }
  158.  
  159.         /*
  160.          * R_BYTE or R_WORD operation
  161.          */
  162.         if (mode & R_BYTE) {
  163.             if (mode & R_BYT2) {
  164.                 relv = add_b2(reli, rtp);
  165.             } else {
  166.                 relv = add_b1(reli, rtp);
  167.             }
  168.         } else {
  169.             relv = add_w(reli, rtp);
  170.         }
  171.  
  172.         /*
  173.          * R_BYTE with R_BYT2 offset adjust
  174.          */
  175.         if (mode & R_BYTE) {
  176.             if (mode & R_BYT2) {
  177.                 rtofst += 1;
  178.             }
  179.         }
  180.  
  181.         /*
  182.          * Unsigned Byte Checking
  183.          */
  184.         if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF)
  185.             error = 1;
  186.  
  187.         /*
  188.          * PCR Relocation Error Checking
  189.          */
  190.         if (mode & R_PCR && mode & R_BYTE) {
  191.             r = relv & ~0x7F;
  192.             if (r != (addr_t) ~0x7F && r != 0)
  193.                 error = 2;
  194.         }
  195.  
  196.         /*
  197.          * Page Relocation Error Checking
  198.          */
  199.         if (mode & R_PAG0 && (relv & ~0xFF || paga || pags))
  200.             error = 3;
  201.         if (mode & R_PAG  && (relv & ~0xFF))
  202.             error = 4;
  203.  
  204.         /*
  205.          * Error Processing
  206.          */
  207.         if (error) {
  208.             rerr.aindex = aindex;
  209.             rerr.mode = mode;
  210.             rerr.rtbase = rtbase + rtp - rtofst - 1;
  211.             rerr.rindex = rindex;
  212.             rerr.rval = relv - reli;
  213.             relerr(errmsg[error-1]);
  214.         }
  215.     }
  216.     if (oflag == 1) {
  217.         ihx(1);
  218.     } else
  219.     if (oflag == 2) {
  220.         s19(1);
  221.     }
  222. }
  223.  
  224. char *errmsg[] = {
  225.     "Unsigned Byte error",
  226.     "Byte PCR relocation error",
  227.     "Page0 relocation error",
  228.     "Page Mode relocation error"
  229. };
  230.  
  231.  
  232. /*
  233.  * Relocation 'P' processing
  234.  */
  235. VOID
  236. relp()
  237. {
  238.     register aindex, rindex;
  239.     int mode, rtp;
  240.     addr_t relv;
  241.     struct areax **a;
  242.     struct sym **s;
  243.  
  244.     /*
  245.      * Get area and symbol lists
  246.      */
  247.     a = hp->a_list;
  248.     s = hp->s_list;
  249.  
  250.     /*
  251.      * Verify Area Mode
  252.      */
  253.     if (eval() != (R_WORD | R_AREA) || eval())
  254.         fprintf(stderr, "P input error\n");
  255.  
  256.     /*
  257.      * Get area pointer
  258.      */
  259.     aindex = evword();
  260.     if (aindex >= hp->h_narea) {
  261.         fprintf(stderr, "P area error\n");
  262.         return;
  263.     }
  264.  
  265.     /*
  266.      * Do remaining relocations
  267.      */
  268.     while (more()) {
  269.         mode = eval();
  270.         rtp = eval();
  271.         rindex = evword();
  272.  
  273.         /*
  274.          * R_SYM or R_AREA references
  275.          */
  276.         if (mode & R_SYM) {
  277.             if (rindex >= hp->h_nglob) {
  278.                 fprintf(stderr, "P symbol error\n");
  279.                 return;
  280.             }
  281.             relv = symval(s[rindex]);
  282.         } else {
  283.             if (rindex >= hp->h_narea) {
  284.                 fprintf(stderr, "P area error\n");
  285.                 return;
  286.             }
  287.             relv = a[rindex]->a_addr;
  288.         }
  289.         add_w(relv, rtp);
  290.     }
  291.  
  292.     /*
  293.      * Paged values
  294.      */
  295.     aindex = add_w(0,2);
  296.     if (aindex >= hp->h_narea) {
  297.         fprintf(stderr, "P area error\n");
  298.         return;
  299.     }
  300.     sdp.s_areax = a[aindex];
  301.     sdp.s_area = sdp.s_areax->a_bap;
  302.     sdp.s_addr = add_w(0,4);
  303.     if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF)
  304.         relerp("Page Definition Boundary Error");
  305. }
  306.  
  307. /*
  308.  * EOF processing
  309.  */
  310. VOID
  311. rele()
  312. {
  313.     if (oflag == 1) {
  314.         ihx(0);
  315.     } else
  316.     if (oflag == 2) {
  317.         s19(0);
  318.     }
  319. }
  320.  
  321. /*
  322.  * Evaluate word
  323.  */
  324. addr_t
  325. evword()
  326. {
  327.     register addr_t v;
  328.  
  329.     if (hilo) {
  330.         v =  (eval() << 8);
  331.         v +=  eval();
  332.     } else {
  333.         v =   eval();
  334.         v += (eval() << 8);
  335.     }
  336.     return(v);
  337. }
  338.  
  339. /*
  340.  * Add byte values
  341.  */
  342. addr_t
  343. add_b1(v, i)
  344. register addr_t v;
  345. register int i;
  346. {
  347.     return(rtval[i] += v);
  348. }
  349.  
  350. /*
  351.  * Add byte values
  352.  */
  353. addr_t
  354. add_b2(v, i)
  355. addr_t v;
  356. int i;
  357. {
  358.     register addr_t j;
  359.  
  360.     if (hilo) {
  361.         j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
  362.         rtflg[i] = 0;
  363.         rtval[i+1] = j & 0xff;
  364.     } else {
  365.         j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
  366.         rtval[i] = j & 0xff;
  367.         rtflg[i+1] = 0;
  368.     }
  369.     return(j);
  370. }
  371.  
  372. /*
  373.  * Add word values
  374.  */
  375. addr_t
  376. add_w(v, i)
  377. register addr_t v;
  378. register int i;
  379. {
  380.     register addr_t j;
  381.  
  382.     if (hilo) {
  383.         j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
  384.         rtval[i] = (j >> 8) & 0xff;
  385.         rtval[i+1] = j & 0xff;
  386.     } else {
  387.         j = v + (rtval[i] & 0xff) + (rtval[i+1] << 8);
  388.         rtval[i] = j & 0xff;
  389.         rtval[i+1] = (j >> 8) & 0xff;
  390.     }
  391.     return(j);
  392. }
  393.  
  394. /*
  395.  * Relocation Error Report
  396.  */
  397. VOID
  398. relerr(str)
  399. char *str;
  400. {
  401.     errdmp(stderr, str);
  402.     if (mfp)
  403.         errdmp(mfp, str);
  404. }
  405.  
  406. /*
  407.  * Relocation error dump routine
  408.  */
  409. VOID
  410. errdmp(fptr, str)
  411. FILE *fptr;
  412. char *str;
  413. {
  414.     int mode, aindex, rindex;
  415.     struct sym **s;
  416.     struct areax **a;
  417.     struct areax *raxp;
  418.  
  419.     a = hp->a_list;
  420.     s = hp->s_list;
  421.  
  422.     mode = rerr.mode;
  423.     aindex = rerr.aindex;
  424.     rindex = rerr.rindex;
  425.  
  426.     /*
  427.      * Print Error
  428.      */
  429.     fprintf(fptr, "\n?ASlink-W-%s", str);
  430.  
  431.     /*
  432.      * Print symbol if symbol based
  433.      */
  434.     if (mode & R_SYM) {
  435.         fprintf(fptr, " for symbol  %.*s\n", NCPS, &s[rindex]->s_id[0]);
  436.     } else {
  437.         fprintf(fptr, "\n");
  438.     }
  439.  
  440.     /*
  441.      * Print Ref Info
  442.      */
  443.     fprintf(fptr,
  444.         "         file        module      area        offset\n");
  445.     fprintf(fptr,
  446.         "  Refby  %-8.8s    %-8.8s    %-8.8s    ",
  447.             hp->h_lfile->f_idp,
  448.             &hp->m_id[0],
  449.             &a[aindex]->a_bap->a_id[0]);
  450.     prntval(fptr, rerr.rtbase);
  451.  
  452.     /*
  453.      * Print Def Info
  454.      */
  455.     if (mode & R_SYM) {
  456.         raxp = s[rindex]->s_axp;
  457.     } else {
  458.         raxp = a[rindex];
  459.     }
  460.     fprintf(fptr,
  461.         "  Defin  %-8.8s    %-8.8s    %-8.8s    ",
  462.             raxp->a_bhp->h_lfile->f_idp,
  463.             &raxp->a_bhp->m_id[0],
  464.             &raxp->a_bap->a_id[0]);
  465.     if (mode & R_SYM) {
  466.         prntval(fptr, s[rindex]->s_addr);
  467.     } else {
  468.         prntval(fptr, rerr.rval);
  469.     }
  470. }
  471.  
  472. VOID
  473. prntval(fptr, v)
  474. FILE *fptr;
  475. addr_t v;
  476. {
  477.     if (xflag == 0) {
  478.         fprintf(fptr, "%04X\n", v);
  479.     } else
  480.     if (xflag == 1) {
  481.         fprintf(fptr, "%06o\n", v);
  482.     } else
  483.     if (xflag == 2) {
  484.         fprintf(fptr, "%05u\n", v);
  485.     }
  486. }
  487.  
  488. /*
  489.  * Paging Error Report
  490.  */
  491. VOID
  492. relerp(str)
  493. char *str;
  494. {
  495.     erpdmp(stderr, str);
  496.     if (mfp)
  497.         erpdmp(mfp, str);
  498. }
  499.  
  500. /*
  501.  * Paging error dump routine
  502.  */
  503. VOID
  504. erpdmp(fptr, str)
  505. FILE *fptr;
  506. char *str;
  507. {
  508.     register struct head *thp;
  509.  
  510.     thp = sdp.s_areax->a_bhp;
  511.  
  512.     /*
  513.      * Print Error
  514.      */
  515.     fprintf(fptr, "\n?ASlink-W-%s\n", str);
  516.  
  517.     /*
  518.      * Print PgDef Info
  519.      */
  520.     fprintf(fptr,
  521.         "         file        module      pgarea      pgoffset\n");
  522.     fprintf(fptr,
  523.         "  PgDef  %-8.8s    %-8.8s    %-8.8s    ",
  524.             thp->h_lfile->f_idp,
  525.             &thp->m_id[0],
  526.             &sdp.s_area->a_id[0]);
  527.     prntval(fptr, sdp.s_area->a_addr + sdp.s_addr);
  528. }
  529.